/*
 * xstdio.cpp
 *
 *  Created on: 15 sept. 2011
 *      Author: lindenb
 */
#include <cerrno>
#include <cstring>
#include "throw.h"
#include "xstdio.h"
#include "xstdlib.h"

using namespace std;

Reader::Reader():buffer(NULL),buffer_size(50)
	{
	buffer=(char*)safeMalloc(buffer_size);
	}
Reader::~Reader()
	{
	free(buffer);
	buffer=NULL;
	}


char* Reader::readLine()
	{
	if(eof()) return NULL;
	int c;
	size_t len=0;
	while((c=getc())!=EOF && c!='\n')
		{
		if(len+2>=buffer_size)
			{
			buffer_size+=2+buffer_size/2;
			buffer=(char*)safeRealloc(buffer,buffer_size*sizeof(char));
			}
		buffer[len++]=c;
		}
	buffer[len]=0;
	return buffer;
	}

StdioReader::StdioReader():owner(false),in(stdin)
	{

	}

StdioReader::StdioReader(FILE* in):owner(false),in(in)
	{

	}
StdioReader::StdioReader(const char* filename):owner(true),in(safeFOpen(filename,"r"))
	{

	}
StdioReader::~StdioReader()
	{
	if(owner) fclose(in);
	}

void StdioReader::close()
	{
	if(owner) fclose(in);
	in=NULL;
	}

int StdioReader::getc()
	{
	return in==NULL?EOF:fgetc(in);
	}

int StdioReader::eof()
	{
	return in==NULL?1:feof(in);
	}

FILE* safeFOpen(const char* filename,const char* mode)
	{
	FILE* in=fopen(filename,mode);
	if(in==NULL) THROW("Cannot open "<< filename << " "<< strerror(errno) );
	return in;
	}




void IOUtils::copyTo(std::FILE* in, ostream& out)
	{
	if(in==NULL) THROW("in==null");
	char buf[BUFSIZ];
	int nRead=0;
	while((nRead=fread(buf,sizeof(char),BUFSIZ,in))!=0)
		{
		out.write(buf,nRead);
		}
	}

void IOUtils::copyTo(std::FILE* in, FILE* out)
	{
	if(in==NULL) THROW("in==null");
	char buf[BUFSIZ];
	int nRead=0;
	while((nRead=fread(buf,sizeof(char),BUFSIZ,in))!=0)
		{
		fwrite(buf,sizeof(char),nRead,out);
		}
	}

void IOUtils::copyFileTo(const char* filename, ostream& out)
	{
	FILE* in=safeFOpen(filename,"r");
	copyTo(in,out);
	fclose(in);
	}

bool IOUtils::fileExists(const char* s)
	{
	FILE*  in=fopen(s,"r");
	if(in==NULL) return false;
	fclose(in);
	return true;
	}

std::string IOUtils::readFileContent(const char* s)
	{
	FILE* in=safeFOpen(s,"r");
	ostringstream os;
	copyTo(in,os);
	fclose(in);
	return os.str();
	}
